#include "Shared.h"

float3 LightPosition = {0.0f, 0.0f, 0.0f};
float3 LightDiffuseColor = {1.0f, 1.0f, 1.0f};
float3 LightSpecularColor = {1.0f, 1.0f, 1.0f};
float LightRadius = 1.0f;
float Phase = 1.0f;

sampler2D DeferredPass_Depth : register( s0 );
sampler2D DeferredPass_Normal : register( s1 );
sampler2D DeferredPass_Scene : register( s2 );
sampler2D DeferredPass_HDR : register( s3 );

samplerCUBE BufferSky : register( s4 );

sampler2D BufferWaterBump : register( s5 );
sampler2D BufferWaterHeight : register( s6 );
sampler2D Check : register( s7 );
sampler2D WaterFoam : register( s8 );
sampler2D WaterCaustics : register( s9 );

sampler2D BufferColor : register( s2 ); 

void vsDeferredShader(float4 positionSys : POSITION0, float2 uv0 : TEXCOORD0, out vsGeometryOut result)
{
    result.positionSys =
    result.position0 = float4(uv0.x, uv0.y, 0.0f, 1.0f);
	result.color0 = 1.0f;
	result.uv0 = 0.0f;
	result.uv1 = 0.0f;
	result.normal0 = 0.0f;
}

void psDeferredEncode(in psGeometryIn vertex,
	out float4 colorDepth : COLOR0,
	out float4 colorNormal : COLOR1,
	out float4 colorTexcoord : COLOR2)
{
	colorNormal.xyz = (normalize(vertex.normal0) * 0.5f) + 0.5f;
	colorNormal.w = 1.0f;
	
	colorDepth =  saturate(vertex.position0.z / vertex.position0.w);
	colorDepth.w = 1.0f;
	
	colorTexcoord = (float4)1;
	colorTexcoord.x = vertex.uv0.x;
	colorTexcoord.y = vertex.uv0.y;
}

void vsShaderFunction(in vsGeometryIn vertex, out vsGeometryOut result)
{
    result.position0 = mul(vertex.position0, World);
    result.position0 = mul(result.position0, View);
    result.position0 = 
    result.positionSys = mul(result.position0, Projection);

	result.normal0 = mul(vertex.normal0, (float3x3)World);
	result.color0 = 1.0f;
	result.uv0 = vertex.uv0;
	result.uv1 = vertex.uv0;
}

  
#define PI 3.14
#define TWOPI 6.28
#define PHASE_DENOMINATOR_WAVE 1.0f
#define PHASE_DENOMINATOR_MOON 2.0f
  

float cosNorm(float phase) {
	return cos(phase) * 0.5f + 0.5f;
}
 

float3 GetWorldSpacePosition(float4 v, float2 c) {
	
	v /= v.w;
	float4 time = mul(float4(v.x, v.y, (float)tex2D(DeferredPass_Depth, c), 1.0f), InvViewProjection);
	return time.xyz / time.www;
}
 
float waveFunction(float oceanHeight,float waveHeight) {
return 2 + cosNorm(oceanHeight) * 0.5 + cosNorm(waveHeight) * 0.5;
}

void psDeferredFunction(in psGeometryIn pixel,
	out float4 outColor : COLOR0)
{
	float2 screen_xy = GetHomogenToScreen(pixel.position0);	
	float3 pixel_ws = GetWorldSpacePosition(pixel.position0, screen_xy); 

	outColor = tex2D(DeferredPass_Scene, screen_xy); 
		  
	float time = frac(-Time*14);
	float pixel_offset = pixel_ws.x;
	float pixel_phase_offset = frac(pixel_offset)  * TWOPI;
	
	float time_pixel_offset = frac(time + pixel_offset) * TWOPI;
	float ocean_phase = time * TWOPI;
	  
	float water_level_at_t = waveFunction(ocean_phase,time_pixel_offset);
	float water_level_at_t0 = waveFunction(0, pixel_phase_offset);
 
	float time_of_peak = time;
	float p = 1 - frac(pixel_offset);
	 
	
	float tmp = (time_of_peak - p);
	if(tmp < 0)
		tmp+=1;
	p = 1 - tmp;
	 
	
	
	float falloff_level = water_level_at_t0  - p;
	if(pixel_ws.y < falloff_level)
		outColor.rgb = float3(1,0,0);
	
	float range_end = 0.5*PI;
	float range_start = TWOPI;
	if(time_pixel_offset > 0.5*PI && time_pixel_offset < TWOPI) {
	
		float range = (range_start - range_end);
		float frac_in_range = (time_pixel_offset - range_end) / range;
		
		//Sqaure causes the lerp to emphise amplitude of inital falloff/ripples, not 
		//so much those towards end of falloff range
		float falloff_endrange = frac_in_range*frac_in_range;
		
		frac_in_range = frac_in_range*0.5;
		
		float tideLiftSpeed = sin(pixel_phase_offset) * 0.5 + 0.5;
		
		float offset = 
		//waveFunction(ocean_phase,0) + 
		water_level_at_t + (tideLiftSpeed * frac_in_range) + 
		frac_in_range * sin(6*(1.54*time_pixel_offset - ocean_phase)) * 0.125;//waveFunction(ocean_phase,0); //water_level_at_t + frac_in_range;
		
		float falloff = lerp(offset, water_level_at_t, falloff_endrange);
		
		if(pixel_ws.y < falloff)
		{
			outColor.rgb = float3(0,1,0);
		}
	}
	
	if(pixel_ws.y < water_level_at_t  )
		outColor.rgb = float3(0,0,1);
}

technique t0
{
    pass pEncode
    {
        VertexShader = compile vs_2_0 vsShaderFunction();
        PixelShader = compile ps_3_0 psDeferredEncode();
    }
    
    pass pWater
    {
        VertexShader = compile vs_2_0 vsDeferredShader();
        PixelShader = compile ps_3_0 psDeferredFunction();
    }
}
